package com.code.AZPlan.client;

import com.code.AZPlan.client.hystrix.AZPlanStaticIncomeClientHystrix;
import com.code.AZPlan.model.bo.*;
import com.code.AZPlan.model.po.*;
import com.code.commons.constants.ServerConstants;
import com.code.commons.service.RestfulCrudService;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 暴露的AZ计划静态收益相关的restful风格的api
 *
 * @author tangyifei
 * @since 2019年12月20日17:44:05
 */
@FeignClient(value = ServerConstants.AZPLAN, path = "AZPlanStaticIncomes", fallback = AZPlanStaticIncomeClientHystrix.class)
public interface AZPlanStaticIncomeClient extends RestfulCrudService<AZPlanBalance, String> {

    /**
     * 刷新内存树
     */
    @GetMapping("/reload-account-tree")
    void reloadAccountTree();

    /**
     * 资金划转
     *
     * @param moneyTransferRecord 资金划转对象
     * @return 资金划转对象
     */
    @PostMapping("/money-transfer")
    MoneyTransferRecord moneyTransfer(@RequestBody MoneyTransferRecord moneyTransferRecord);

    /**
     * 兑换
     *
     * @param exchangeFlow 兑换流水对象
     * @return 兑换流水对象
     */
    @PostMapping("/exchange")
    ExchangeFlow insertExchangeFlow(@RequestBody ExchangeFlow exchangeFlow);

    /**
     * 用户入金
     *
     * @param entryMoneyBO 入金业务对象
     * @return 用户入金业务对象
     */
    @PatchMapping("/entry-money")
    EntryMoneyBO entryMoney(@RequestBody EntryMoneyBO entryMoneyBO) throws Exception;

    /**
     * 根据用户主键获取用户的矿池大小
     *
     * @param userId 用户主键
     * @return 矿池大小
     */
    @GetMapping("/{userId}/balance")
    AZPlanBalance getAZPlanBalanceByUserId(@PathVariable("userId") String userId);

    /**
     * 通过用户主键和币种类型获取资金划转信息
     *
     * @param userId       用户主键
     * @param coinType     币种类型
     * @param coinAddress  币种地址
     * @param transferType 1表示从钱包划转到AZ计划   2表示从AZ计划划转到钱包
     * @return 资金划转实体
     */
    @GetMapping("/{userId}/get-money-transfer")
    MoneyTransferRecord getMoneyTransferByUserIdAndCoinType(@PathVariable("userId") String userId,
                                                            @RequestParam(value = "coinType", required = false) String coinType,
                                                            @RequestParam(value = "coinAddress", required = false) String coinAddress,
                                                            @RequestParam(value = "transferType", required = false) Integer transferType);

    /**
     * 通过用户主键获取剩余矿池的大小
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 剩余矿池大小
     */
    @GetMapping("/get-ore-pool")
    Map<String, Object> getOrePool(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 根据用户主键获取用户得到的总的收益（包括静态收益和动态收益）
     *
     * @param userId 用户主键
     * @return 总的收益（包括静态收益和动态收益）
     */
    @GetMapping("/get-total-income-amount")
    BigDecimal getTotalIncomeAmount(@RequestParam("userId") String userId);

    /**
     * 根据用户主键获取XWC金额
     *
     * @param userId 用户主键
     * @return XWC金额
     */
    @GetMapping("/get-total-xwc-amount")
    BigDecimal getTotalXWCAmount(@RequestParam("userId") String userId);

    /**
     * 根据用户主键获取BTC兑换金额
     *
     * @param userId 用户主键
     * @return BTC兑换金额
     */
    @GetMapping("/get-total-btc-amount")
    BigDecimal getTotalBTCAmount(@RequestParam("userId") String userId);

    /**
     * 根据用户主键获取兑换总金额
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 兑换总金额
     */
    @GetMapping("/get-total-exchange-amount")
    BigDecimal getTotalExchangeAmount(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 根据用户主键获取用户钱包金额
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 钱包总金额
     */
    @GetMapping("/get-total-wallet-amount")
    BigDecimal getTotalWalletAmount(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 根据用户主键获取总的资金划转金额
     *
     * @param userId       用户主键
     * @param coinType     币种类型
     * @param transferType 1表示从钱包划转到AZ计划   2表示从AZ计划划转到钱包
     * @return 兑换总金额
     */
    @GetMapping("/get-total-money-transfer-amount")
    BigDecimal getTotalMoneyTransferAmount(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType,
                                           @RequestParam("transferType") Integer transferType);

    /**
     * 通过用户主键获取收益
     *
     * @param userId   用户主键
     * @param page     当前页码
     * @param pageSize 每页的大小
     * @return 收益流水
     */
    @GetMapping("/{userId}/incomes")
    Map<String, Object> getIncomes(@PathVariable("userId") String userId, @RequestParam(value = "page", required = false) Integer page,
                                   @RequestParam(value = "pageSize", required = false) Integer pageSize) throws Exception;

    /**
     * 通过用户主键获取收益
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @param page     当前页码
     * @param pageSize 每页的大小
     * @return 收益流水
     */
    @GetMapping("/{userId}/usd-bills")
    Map<String, Object> getUsdBills(@PathVariable("userId") String userId, @RequestParam("coinType") String coinType,
                                    @RequestParam(value = "page", required = false) Integer page,
                                    @RequestParam(value = "pageSize", required = false) Integer pageSize);

    /**
     * 获取用户AZ计划钱包的信息
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return AZ计划钱包的信息
     */
    @GetMapping("/get-az-plan-wallet")
    AZPlanWallet getAZPlanWallet(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 获取某一个用户的相关币种转入与转出流水
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 某一个用户的相关币种转入与转出流水
     */
    @GetMapping("/get-transfer-in-out-flow-list")
    List<TransferInOutFlow> getTransferInOutFlowList(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType,
                                                     @RequestParam(value = "flowType", required = false) Integer flowType);

    /**
     * 提币
     *
     * @param withdrawOrder 提币PO对象
     */
    @PostMapping("/withdraw")
    int withdraw(@RequestBody WithdrawOrder withdrawOrder);

    /**
     * 获取提币订单
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 提币订单
     */
    @GetMapping("/get-withdraw-order")
    List<WithdrawOrder> getWithdrawOrderList(@RequestParam(value = "userId", required = false) String userId, @RequestParam(value = "coinType", required = false) String coinType);

    /**
     * 获取推荐人的usdt版本号和矿池版本号
     *
     * @param userId 被推荐人的用户主键
     * @return 推荐人的usdt版本号和矿池版本号
     */
    @GetMapping("/get-usdt-ore-pool-version")
    List<UserRelativeVersionBO> getUserRelativeVersionBOList(@RequestParam("userId") String userId);

    /**
     * 获取所有用户的矿池版本号
     *
     * @return 所有用户的矿池版本号对象
     */
    @GetMapping("/get-all-user-ore-pool-version")
    List<AZPlanBalance> getUserOrePoolVersionList();

    /**
     * 获取所有用户的矿池版本号
     *
     * @return 所有用户的矿池版本号对象
     */
    @GetMapping("/get-entry-money-flow-list")
    List<EntryMoneyFlow> getEntryMoneyFlowList();

    /**
     * 获取提币订单列表
     *
     * @return 提币订单列表
     */
    @PostMapping("/wallets/get-withdraw-list")
    WithdrawBO getWithdrawList(@RequestBody WithdrawBO withdrawBO);

    /**
     * 获取提币订单
     *
     * @return 提币订单
     */
    @GetMapping("/wallets/get-withdraw-order")
    WithdrawOrder getWithdrawOrder(@RequestParam("id") String id);

    /**
     * 更新提币订单
     *
     * @param withdrawOrder 提币订单对象
     * @return 影响的行数
     */
    @PatchMapping("/update-withdraw-order")
    int updateWithdrawOrder(@RequestBody WithdrawOrder withdrawOrder);

    /**
     * 手动执行定时任务
     */
    @GetMapping("/generate-static-income")
    void generateStaticIncome();

    /**
     * 手动打印内存树
     *
     * @return 内存树
     */
    @GetMapping(value = "/manual-print-memory-tree")
    String manualPrintMemoryTree(@RequestParam(value = "userPhone", required = false) String userId);

    /**
     * 获取对应父账户下面的所有子账户累计入金金额
     */
    @GetMapping("/get-all-child-account-total-entry-amount")
    BigDecimal getAllChildAccountTotalEntryAmount(@RequestParam(value = "userId", required = false) String userId);

    /**
     * 获取所有的间接子节点列表
     */
    @GetMapping("/get-indirect-children-recommends")
    Map<String, Object> getIndirectRecommends(@RequestParam(value = "parentId") String parentId,
                                              @RequestParam(value = "entryMoneyState", required = false) Integer entryMoneyState,
                                              @RequestParam(value = "page", required = false) Integer page,
                                              @RequestParam(value = "pageSize", required = false) Integer pageSize);

    /**
     * 获取充值列表
     *
     * @param rechargeTranBO 充值记录对象
     * @return 充值列表
     */
    @PostMapping("/wallets/get-deposit-list")
    RechargeTranBO getDepositList(@RequestBody RechargeTranBO rechargeTranBO);

    /**
     * 获取用户资产列表
     *
     * @param userAssetBO 用户资产业务对象
     * @return 用户资产列表
     */
    @PostMapping("/wallets/get-user-assets")
    UserAssetBO getUserAssetList(@RequestBody UserAssetBO userAssetBO);

    /**
     * 标记内部用户
     *
     * @param userId 用户id
     */
    @PatchMapping("/markInnerUser")
    void markInnerUser(@RequestParam(value = "userId", required = false) String userId);

    /**
     * 获取入金列表
     *
     * @param entryMoneyFlowBO 用户入金流水业务对象
     * @return 用户入金列表
     */
    @PostMapping("/wallets/get-entry-money-list")
    EntryMoneyFlowBO getEntryMoneyFlowList(@RequestBody EntryMoneyFlowBO entryMoneyFlowBO);

    /**
     * 获取兑换流水列表
     *
     * @param exchangeFlowBO 用户兑换流水业务对象
     * @return 用户兑换列表
     */
    @PostMapping("/wallets/get-exchange-list")
    ExchangeFlowBO getExchangeFlowList(@RequestBody ExchangeFlowBO exchangeFlowBO);

    /**
     * 获取收益统计日报列表
     *
     * @param incomeStatisticsDailyBO 收益统计日报业务对象
     * @return 收益统计日报列表
     */
    @PostMapping("/wallets/get-income-statistics-list")
    IncomeStatisticsDailyBO getIncomeStatisticsList(@RequestBody IncomeStatisticsDailyBO incomeStatisticsDailyBO);

    /**
     * 获取收益明细列表
     *
     * @param incomeStatisticsDailyBO 收益统计日报业务对象
     * @return 收益明细列表
     */
    @PostMapping("/wallets/get-income-detail-list")
    IncomeStatisticsDailyBO getIncomeDetailList(@RequestBody IncomeStatisticsDailyBO incomeStatisticsDailyBO);

    /**
     * 站内转账
     *
     * @param inSiteUserBO 站内转账业务对象
     * @return 影响的行数
     */
    @PostMapping("/in-site-transfer")
    int inSiteTransfer(@RequestBody InSiteUserBO inSiteUserBO);

    /**
     * 根据用户主键和币种类型获取未审核的（冻结的）的提币总金额
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 冻结的金额
     */
    @GetMapping("/get-frozen-amount")
    BigDecimal getFrozenAmount(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 添加公告
     *
     * @param azNotice 公告对象
     * @return 影响的行数
     */
    @PostMapping("/notices")
    int addAzNotice(@RequestBody AzNotice azNotice);

    /**
     * 修改公告
     *
     * @param azNotice 公告对象
     * @return 影响的行数
     */
    @PatchMapping("/notices")
    int updateAzNotice(@RequestBody AzNotice azNotice);

    /**
     * 根据公告主键查询单个公告
     *
     * @param id 主键
     * @return 公告对象
     */
    @GetMapping("/notices/{id}")
    AzNotice getAzNoticeById(@PathVariable("id") String id);

    /**
     * 根据相关的检索条件获取公告列表
     *
     * @param azNoticeBO 公告业务对象
     * @return 公告业务对象
     */
    @PostMapping("/notices/get-notice-list")
    AzNoticeBO getAzNoticeList(AzNoticeBO azNoticeBO);

    /**
     * 修改公告的上线与下线状态
     *
     * @param azNotice 公告对象
     * @return 影响的行数
     */
    @PatchMapping("/notices/up-down")
    int upDownAzNotice(AzNotice azNotice);
}
